package com.briup.upload.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.briup.common.exception.CustomerException;
import com.briup.common.web.MessageStatus;
import com.briup.upload.constants.UploadConstants;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 阿里云OSS存储工具类
 */
public class OSSUploadRemoteServiceImpl {

    public List<String> uploadRemoteFile(MultipartFile[] files,String args) throws CustomerException {
        List<String> list = new ArrayList<>();

        if(files!=null && files.length>0) {
            Arrays.stream(files).forEach(file->{
                list.add(uploadFile(file));
            });
        }

        return list;
    }

    private String uploadFile(MultipartFile file) {
        try {
            return uploadFileToOSSWithOutExpiration(file);
        } catch (IOException e) {
            throw new CustomerException(MessageStatus.UPLOAD_FILE_ERROR);
        }
    }


    /**
     * 上传文件到oss，并且返回文件访问地址，地址永久生效
     * 需要在oss设置bucket为公共的（可读写权限）
     * @param file
     * @return 文件访问地址
     * @throws IOException
     */
    private String uploadFileToOSSWithOutExpiration(MultipartFile file) throws IOException {
        OSS ossClient = new OSSClientBuilder().build(UploadConstants.ALIYUN_OSS_ENDPOINT, UploadConstants.ALIYUN_OSS_ACCESSKEYID, UploadConstants.ALIYUN_OSS_ACCESSKEYSECRET);

        String objectName = uploadFileToOSS(file, ossClient);
        String url = "http://"+UploadConstants.ALIYUN_OSS_BUCKETNAME+"."+UploadConstants.ALIYUN_OSS_ENDPOINT+"/"+objectName;

        ossClient.shutdown();
        return url;
    }

    /**
     * 上传文件到oss，并且返回文件访问地址，地址具有有效期
     * 需要在oss设置bucket为私有的（ACL）,其实只要设置过去时间就可以了，bucket不是私有的也行
     * @param file
     * @param millis 过期时间，单位毫秒，UploadConstants#ALIYUN_OSS_EXPIRATION_HOUR
     * @return 文件访问地址
     * @throws IOException
     */
    private String uploadFileToOSSWithExpiration(MultipartFile file,long millis) throws IOException {
        OSS ossClient = new OSSClientBuilder().build(UploadConstants.ALIYUN_OSS_ENDPOINT, UploadConstants.ALIYUN_OSS_ACCESSKEYID, UploadConstants.ALIYUN_OSS_ACCESSKEYSECRET);

        String objectName = uploadFileToOSS(file, ossClient);

        Date expiration = new Date(System.currentTimeMillis() + millis);
        String url = ossClient.generatePresignedUrl(UploadConstants.ALIYUN_OSS_BUCKETNAME, objectName, expiration).toString();

        ossClient.shutdown();
        return url;
    }

    /**
     * 该方法做以下事情：
     * 1 设置上传到的文件夹（现在是默认当前日期作为文件夹）
     * 2 设置上传的文件名
     * 3 上传文件到oss
     * @param file
     * @param ossClient
     * @return OSS上传后的对象名，由 文件夹+文件名 组成的
     * @throws IOException
     */
    private String uploadFileToOSS(MultipartFile file, OSS ossClient) throws IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        // 获取文件名
        String fileName = file.getOriginalFilename();
        // 获取文件后缀名
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        // 最后上传生成的文件名
        String finalFileName = System.currentTimeMillis() + "" + suffixName;
        // oss中对象名，由 文件夹+文件名 组成的
        String objectName = sdf.format(new Date()) + "/" + finalFileName;
        // 创建上传文件的元信息，可以通过文件元信息设置HTTP header(设置了才能通过返回的链接直接访问)。
        switch (suffixName){
            case "":
        }
        ObjectMetadata objectMetadata = new ObjectMetadata();
//        objectMetadata.setContentType("image/jpg");
        objectMetadata.setContentType("*/*");
        // 文件上传
        ossClient.putObject(UploadConstants.ALIYUN_OSS_BUCKETNAME, objectName, new ByteArrayInputStream(file.getBytes()), objectMetadata);

        return objectName;
    }

}
